﻿//////////////////////////////////////////////////////////////////
//
// Hester\Program.cs
//
// Copyright (c) 2012 Dan Pike.
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation files
// (the "Software"), to deal in the Software without restriction,
// including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so,
// subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using DanPike.Utilities;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;

namespace Hester
{
   static class Program
   {
      public const string HesterId = "C56276C4-1552-4A2F-A981-DC2F9AB8D76F";
      private static Logger logger_;
      public static Configuration AppConfig;
      public static Config.Hester Settings;
      public static EventWaitHandle ProgramRunning;
      public static Main MainForm;

      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// 
      /// </summary>
      public static Logger Logger
      {
         get
         {
            if (null == logger_)
            {
               logger_ = new Logger();
            }
            return logger_;
         }
      }

      //////////////////////////////////////////////////////////////////////////
      //
      private static T loadConfiguration<T>(string sectionName) where T : ConfigurationSection, new()
      {
         try
         {
            AppConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            T settings = AppConfig.GetSection(sectionName) as T;
            if (null == settings)
            {
               settings = new T();
               AppConfig.Sections.Add(sectionName, settings);
               AppConfig.Save(ConfigurationSaveMode.Full);
            }
            return settings;
         }
         catch (System.Exception ex)
         {
            Logger.Exception(ex);
         }
         return null;
      }

      ////////////////////////////////////////////////////////////////////////
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         bool createdNew = false;
         try
         {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            // Prevent duplication
            using (ProgramRunning = new EventWaitHandle(false, EventResetMode.ManualReset, HesterId, out createdNew))
            {
               if (!createdNew)
               {
                  MessageBox.Show(string.Concat(Application.ProductName, " is already running, this will now close"),
                     Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Stop);
                  return;
               }

               MainForm = new Main();

               // Load the program's settings from the exe.config ...
               Logger.DebugFormat("loading configuration");
               if (null == (Settings = loadConfiguration<Config.Hester>(Config.Hester.CONFIG_SECTION)))
               {
                  Logger.ErrorFormat("failed to load configuration file");
                  return;
               }
               // ... and link to the Network config section for our own stuff, too
               if (null == (Settings = AppConfig.GetSection(Config.Hester.CONFIG_SECTION) as Config.Hester))
               {
                  Logger.ErrorFormat("configuration file does not have section '{0}'",
                     Config.Hester.CONFIG_SECTION);
                  return;
               }

               string sectionName = Config.Hester.CONFIG_SECTION;
               if (null == (Settings = AppConfig.GetSection(sectionName) as Config.Hester))
               {
                  Logger.ErrorFormat("could not find section '{0}' in configuration file '{1}'",
                     sectionName, AppConfig.FilePath);
                  return;
               }

               Application.Run(MainForm);
            }
         }
         catch (System.Exception ex)
         {
            Logger.Exception(ex);
         }
      }
   }
}
